package com.zhc.validate;

import java.lang.reflect.*;
import java.util.*;
import java.time.*;
import java.util.stream.*;
import java.util.function.*;

public class RandomArgumentGenerator {

    public Object algorithm(Object... args) {
        System.out.println("Received args: " + Arrays.toString(args));
        return null;
    }

    public Object[] generateRandomArguments(Method method) {
        Parameter[] parameters = method.getParameters();
        List<Object> randomArgs = new ArrayList<>();

        for (Parameter parameter : parameters) {
            Class<?> parameterType = parameter.getType();
            Object randomValue = generateRandomValue(parameterType);
            randomArgs.add(randomValue);
        }

        return randomArgs.toArray();
    }

    private Object generateRandomValue(Class<?> clazz) {
        Random random = new Random();

        // 基本类型 & 包装类型
        if (clazz == int.class || clazz == Integer.class) {
            return random.nextInt(100);
        } else if (clazz == double.class || clazz == Double.class) {
            return random.nextDouble() * 100;
        } else if (clazz == long.class || clazz == Long.class) {
            return random.nextLong();
        } else if (clazz == boolean.class || clazz == Boolean.class) {
            return random.nextBoolean();
        } else if (clazz == char.class || clazz == Character.class) {
            return (char) (random.nextInt(26) + 'a');
        } else if (clazz == float.class || clazz == Float.class) {
            return random.nextFloat() * 100;
        } else if (clazz == byte.class || clazz == Byte.class) {
            return (byte) random.nextInt(256);
        } else if (clazz == short.class || clazz == Short.class) {
            return (short) random.nextInt(Short.MAX_VALUE);
        }

        // String
        else if (clazz == String.class) {
            return generateRandomString(10);
        }

        // 数组类型
        else if (clazz.isArray()) {
            return generateRandomArray(clazz.getComponentType(), 5);  // 生成数组，长度为 5
        }

        // List 和 Set
        else if (List.class.isAssignableFrom(clazz)) {
            return generateRandomList(clazz, 5);  // List 中包含 5 个随机元素
        }

        // Map
        else if (Map.class.isAssignableFrom(clazz)) {
            return generateRandomMap(clazz);  // Map 类型的随机生成
        }

        // 枚举类型
        else if (clazz.isEnum()) {
            return generateRandomEnum(clazz);
        }

        // 日期类型
        else if (clazz == Date.class) {
            return new Date();  // 当前日期
        } else if (clazz == LocalDate.class) {
            return LocalDate.now().plusDays(new Random().nextInt(365));
        } else if (clazz == LocalDateTime.class) {
            return LocalDateTime.now().plusHours(new Random().nextInt(1000));
        }

        // Optional
        else if (clazz == Optional.class) {
            return Optional.of(generateRandomValue(clazz.getComponentType()));
        }

        // 自定义类 (递归处理字段)
        else if (clazz.getPackage().getName().startsWith("java.lang") == false) {
            return generateRandomCustomObject(clazz);
        }

        // 默认返回 null
        return null;
    }

    // 生成随机字符串
    private String generateRandomString(int length) {
        String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        StringBuilder sb = new StringBuilder(length);
        Random random = new Random();
        for (int i = 0; i < length; i++) {
            sb.append(chars.charAt(random.nextInt(chars.length())));
        }
        return sb.toString();
    }

    // 生成随机数组
    private Object generateRandomArray(Class<?> componentType, int length) {
        Object array = Array.newInstance(componentType, length);
        for (int i = 0; i < length; i++) {
            Array.set(array, i, generateRandomValue(componentType));
        }
        return array;
    }

    // 生成随机 List
    private List<Object> generateRandomList(Class<?> listType, int size) {
        List<Object> list = new ArrayList<>();
        // 如果 List 的元素是 String 或其他基本类型，生成相应的随机元素
        for (int i = 0; i < size; i++) {
            list.add(generateRandomValue(listType.getComponentType()));
        }
        return list;
    }

    // 生成随机 Map
    private Map<String, Object> generateRandomMap(Class<?> mapType) {
        Map<String, Object> map = new HashMap<>();

        // 获取 Map 的值类型（假设 key 是 String 类型）
        Type[] genericTypes = ((ParameterizedType) mapType.getGenericSuperclass()).getActualTypeArguments();
        Class<?> keyType = String.class;  // 默认的 key 类型是 String
        Class<?> valueType = (Class<?>) genericTypes[1];  // 获取 Map 值的类型

        int size = 5;  // 假设生成 5 对键值对
        for (int i = 0; i < size; i++) {
            String key = generateRandomString(5);  // 生成随机字符串作为 key
            Object value = generateRandomValue(valueType);  // 生成随机值
            map.put(key, value);
        }
        return map;
    }

    // 生成随机 Enum
    private Object generateRandomEnum(Class<?> enumClass) {
        Object[] enumValues = enumClass.getEnumConstants();
        return enumValues[new Random().nextInt(enumValues.length)];
    }

    // 生成随机自定义对象
    private Object generateRandomCustomObject(Class<?> clazz) {
        try {
            Object instance = clazz.getDeclaredConstructor().newInstance();
            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                field.set(instance, generateRandomValue(field.getType()));
            }
            return instance;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) throws Exception {
        RandomArgumentGenerator generator = new RandomArgumentGenerator();
        
        // 假设我们有一个方法
        Method method = RandomArgumentGenerator.class.getMethod("algorithm", Object[].class);

        // 生成随机参数
        Object[] randomParams = generator.generateRandomArguments(method);

        // 调用算法方法并传入随机参数
        generator.algorithm(randomParams);
    }
}
